package com.googlecode.grima.servlet;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.googlecode.grima.util.IOUtil;

public class DiagramServlet extends HttpServlet {

	private static final long serialVersionUID = -5106292230306205506L;
	
	private RepositoryService repositoryService;
	private RuntimeService runtimeService;
	
	@Override
	public void init(ServletConfig config) throws ServletException {
	  super.init(config);
	  
	  WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(config.getServletContext());
	  this.repositoryService = (RepositoryService) springContext.getBean("repositoryService");
	  this.runtimeService = (RuntimeService) springContext.getBean("runtimeService");
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		String processDefinitionId = request.getParameter("processDefinitionId");
		String processInstanceId = request.getParameter("processInstanceId");
		
		if ( (processDefinitionId == null) && (processInstanceId == null)) {
			response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
			return;
		}

		InputStream is = null;
		
		if (processInstanceId != null) {
			is = getProcessInstanceImage(processInstanceId);
			if (is == null) {
				response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
				return;
			}
			
		} else {

			if (processDefinitionId != null) {
				is = getProcessDefinitionImage(processDefinitionId);
				if (is == null) {
					response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
					return;
				}
			}
		}

		OutputStream os;
		try {
			os = response.getOutputStream();
			IOUtil.copyStream(is, os);
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public InputStream getProcessDefinitionImage(String processDefinitionId) {

		InputStream ret = null;

		BpmnModel model = repositoryService.getBpmnModel(processDefinitionId);
		List<String> highlightedActivities = new ArrayList<String>();
		ret = new DefaultProcessDiagramGenerator().generateDiagram(model, "png", highlightedActivities);
			
		return ret;
	}
	

	public InputStream getProcessInstanceImage(String processInstanceId) {

		InputStream ret = null;

		Set<String> processInstanceIds = new HashSet<String>();
		processInstanceIds.add(processInstanceId);
		List<ProcessInstance> instances = runtimeService.createProcessInstanceQuery().processInstanceIds(processInstanceIds).list();

		if (instances.size() > 0){
			ProcessInstance processInstance = instances.get(0);
			String processDefinitionId = processInstance.getProcessDefinitionId();
			BpmnModel model = repositoryService.getBpmnModel(processDefinitionId);
			List<String> highlightedActivities = runtimeService.getActiveActivityIds(processInstanceId);
			ret = new DefaultProcessDiagramGenerator().generateDiagram(model, "png", highlightedActivities);
		}
			
		return ret;
	}


}